﻿using System;
using System.Net;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Documents;
using System.Windows.Ink;
using System.Windows.Input;
using System.Windows.Media;
using System.Windows.Media.Animation;
using System.Windows.Shapes;
using predic.Web.Host.Model;
using System.Collections.Generic;
using predic.Web.Host.Services;
using System.Linq;
using System.Threading;
using System.Windows.Data;
using predic.Web.Infrastructure.Commands;
using System.Text;


namespace predic.Web.Model
{
    public class MaintainPredici : Infrastructure.Model.BaseModel
    {

        #region Private Fields

        private PredicContext ctx;
        private const string formatSummaryStart = "{0}:{1} ";

        #endregion

        #region UI Flags

        public bool IsNewPreacher
        {
            get
            {
                if (SelectedPreacher == null)
                    return true;

                return false;
            }
        }
        public bool IsNewTitle
        {
            get
            {
                if (SelectedTitle == null)
                    return true;

                return false;
            }
        }
        public bool IsNewSubtitle
        {
            get
            {
                if (SelectedSubtitle == null)
                    return true;

                return false;
            }
        }

        #endregion



        #region Preacher

        private Preacher selectedPreacher;
        public Preacher SelectedPreacher
        {
            get { return selectedPreacher; }
            set
            {
                selectedPreacher = value;
                OnPreacherChanged();
            }
        }

        private string preacherFullName;
        public string PreacherFullName
        {
            get { return preacherFullName; }
            set
            {
                preacherFullName = value;
                this.NotifyProperty(a => this.PreacherFullName);
            }
        }

        private List<Preacher> preachersList;
        public List<Preacher> PreachersList
        {
            get
            {
                return preachersList;
            }
            set
            {
                preachersList = value;
                this.NotifyProperty(a => this.PreachersList);
            }
        }

        #endregion

        #region Study

        private List<Study> studyList;
        public List<Study> StudyList
        {
            get
            {
                return studyList;
            }
            set
            {
                studyList = value;
                this.NotifyProperty(a => this.StudyList);

                StudyListPaged = null;
                this.NotifyProperty(a => this.StudyListPaged);
            }
        }

        private PagedCollectionView studyListPaged;
        public PagedCollectionView StudyListPaged
        {
            get
            {
                studyListPaged = new PagedCollectionView(StudyList);
                return studyListPaged;
            }

            set
            {
                studyListPaged = value;
                this.NotifyProperty(a => this.StudyListPaged);
            }
        }

        #endregion

        #region Title

        private CustomStringTransport selectedTitle;
        public CustomStringTransport SelectedTitle
        {
            get
            {
                return selectedTitle;
            }
            set
            {
                selectedTitle = value;
                OnTitleChanged();
            }
        }

        private string title;
        public string Title
        {
            get { return title; }
            set
            {
                title = value;
                NotifyProperty(a => this.Title);
            }
        }

        private List<CustomStringTransport> titleList;
        public List<CustomStringTransport> TitleList
        {
            get
            {
                return titleList;
            }
            set
            {
                titleList = value;
                //NotifyProperty(a => this.TitleList);
                NotifyProperty("TitleList");
            }
        }

        #endregion

        #region Subtitle
        private CustomStringTransport selectedSubtitle;
        public CustomStringTransport SelectedSubtitle
        {
            get
            {

                return selectedSubtitle;
            }
            set
            {
                selectedSubtitle = value;
                OnSubtitleChanged();
            }
        }

        private string subtitle;
        public string Subtitle
        {
            get { return subtitle; }
            set
            {
                subtitle = value;
                NotifyProperty(a => this.Subtitle);
            }
        }

        private List<CustomStringTransport> subtitleList;
        public List<CustomStringTransport> SubtitleList
        {
            get
            {
                return subtitleList;
            }
            set
            {
                subtitleList = value;
                //NotifyProperty(a => this.SubtitleList);
                NotifyProperty("SubtitleList");
            }
        }

        #endregion

        #region Text


        private string text;
        public string Text
        {
            get { return text; }
            set
            {
                text = value;
                NotifyProperty(a => this.Text);
            }
        }
        #endregion

        #region Tematica

        private string tematica;
        public string Tematica
        {
            get { return tematica; }
            set
            {
                tematica = value;
                NotifyProperty(a => this.Tematica);
            }
        }
        #endregion

        #region Subiect

        private string subiect;
        public string Subiect
        {
            get { return subiect; }
            set
            {
                subiect = value;
                //NotifyProperty(a => this.Subiect);
                NotifyProperty("Subiect");
            }
        }
        #endregion

        #region SelectionSummary

        public string SelectionSummary
        {
            get
            {
                StringBuilder summaryBuilder = new StringBuilder();

                if (SelectedPreacher != null)
                    summaryBuilder.Append(string.Format(formatSummaryStart, "Predicator", SelectedPreacher.FullName));

                if (SelectedTitle != null)
                    summaryBuilder.Append(string.Format(formatSummaryStart, "Titlu", SelectedTitle.CustomValue));

                if (SelectedTitle != null)
                    summaryBuilder.Append(string.Format(formatSummaryStart, "Titlu", SelectedTitle.CustomValue));

                return summaryBuilder.ToString();
            }
        }

        #endregion


        #region Ctor

        public MaintainPredici()
        {
            ctx = Core.DataContext.Context;

            StudyList = new List<Study>();
            StudyInlineVisibility = Visibility.Collapsed;

            GetPreachers();
            InitCommands();
        }

        private void InitCommands()
        {
            NewCommand = new ButtonCommand(NewCommandAction);
            SaveCommand = new ButtonCommand(SaveCommandAction);
            DeleteCommand = new ButtonCommand(DeleteCommandAction);
        }

        #endregion

        #region Init Controls with Data

        private void GetPreachers()
        {
            //ctx = new PredicContext();

            this.IsBusy = true;
            this.BusyMessage = "InitPreachers";

            ctx.Load<Preacher>(ctx.GetPreachersQuery(),
                (loadOperation_Preacher) =>
                {
                    PreachersList = loadOperation_Preacher.Entities.ToList<Preacher>();
                    this.IsBusy = false;
                },
                null);
        }

        private void GetStudyByPreacher()
        {
            //ctx = new PredicContext();

            if (SelectedPreacher != null)
            {
                this.IsBusy = true;
                this.BusyMessage = "InitStudy";

                ctx.Load<Study>(ctx.GetStudiesByPreacherQuery(SelectedPreacher.ID),
                    (loadOperation_Study) =>
                    {
                        StudyList = loadOperation_Study.Entities.ToList<Study>();
                        this.IsBusy = false;
                    },
                    null);
            }
        }

        private void GetStudyByAllCriteria()
        {
            //ctx = new PredicContext();

            if (SelectedPreacher != null)
            {
                this.IsBusy = true;
                this.BusyMessage = "InitStudy";

                ctx.Load<Study>(ctx.GetStudiesByCriteriaQuery(SelectedPreacher.ID, this.Title, this.Subtitle, "", "", ""),
                    (loadOperation_Study) =>
                    {
                        if (loadOperation_Study.HasError)
                        {
                            var error = loadOperation_Study.Error.Message;
                        }

                        StudyList = loadOperation_Study.Entities.ToList<Study>();
                        this.IsBusy = false;
                    },
                    null);
            }
        }

        private void GetDistinctTitleByPreacher()
        {
            //ctx = new PredicContext();

            if (SelectedPreacher != null)
            {
                this.IsBusy = true;
                this.BusyMessage = "GetDistinctTitleByPreacher";

                ctx.Load<CustomStringTransport>(ctx.GetDistinctTitlesByPreacherQuery(SelectedPreacher.ID),
                    (loadOperation_Study) =>
                    {
                        TitleList = loadOperation_Study.Entities.ToList<CustomStringTransport>();
                        this.IsBusy = false;
                    },
                    null);
            }
        }

        private void GetDistinctSubtitleByPreacher()
        {
            //ctx = new PredicContext();

            if (SelectedPreacher != null)
            {
                this.IsBusy = true;
                this.BusyMessage = "GetDistinctSubtitleByPreacher";

                ctx.Load<CustomStringTransport>(ctx.GetDistinctSubtitlesByPreacherQuery(SelectedPreacher.ID),
                    (loadOperation_Study) =>
                    {
                        SubtitleList = loadOperation_Study.Entities.ToList<CustomStringTransport>();
                        this.IsBusy = false;
                    },
                    null);
            }
        }

        private void GetDistinctSubtitleByPreacherAndTitle()
        {
            //ctx = new PredicContext();

            if (SelectedPreacher != null)
            {
                this.IsBusy = true;
                this.BusyMessage = "GetDistinctSubtitleByPreacher";

                ctx.Load<CustomStringTransport>(ctx.GetDistinctSubtitlesByPreacherAndTitleQuery(SelectedPreacher.ID, Title),
                    (loadOperation_Study) =>
                    {
                        SubtitleList = loadOperation_Study.Entities.ToList<CustomStringTransport>();
                        this.IsBusy = false;
                    },
                    null);
            }
        }

        #endregion

        #region OnChanges

        private void OnPreacherChanged()
        {
            FilterStudyByPreacher();

            GetDistinctTitleByPreacher();
            GetDistinctSubtitleByPreacher();
        }

        private void OnTitleChanged()
        {
            if (!IsNewTitle)
            {
                GetStudyByAllCriteria();
                GetDistinctSubtitleByPreacherAndTitle();
            }
        }

        private void OnSubtitleChanged()
        {
            if (!IsNewSubtitle)
            {
                GetStudyByAllCriteria();
            }
        }

        #endregion

        #region Filter Data

        private void FilterStudyByPreacher()
        {
            if (!IsNewPreacher)
            {
                GetStudyByPreacher();
            }
            else
            {
                ClearAllControls();
            }
        }

        private void ClearAllControls()
        {
            PreacherFullName = string.Empty;
            Title = string.Empty;
            Subtitle = string.Empty;
            Text = string.Empty;
            Tematica = string.Empty;
            Subiect = string.Empty;

            if (StudyList != null)
            {
                StudyList.Clear();
                this.NotifyProperty("StudyList");
            }

            if (StudyListPaged != null)
            {
                StudyListPaged.Refresh();
                this.NotifyProperty("StudyListPaged");
            }

            if (TitleList != null)
            {
                TitleList.Clear();
                this.NotifyProperty("TitleList");
            }

            if (SubtitleList != null)
            {
                SubtitleList.Clear();
                this.NotifyProperty("SubtitleList");
            }
        }

        #endregion

        #region Button Commands

        public ButtonCommand NewCommand { get; private set; }
        public ButtonCommand SaveCommand { get; private set; }
        public ButtonCommand DeleteCommand { get; private set; }

        private void NewCommandAction()
        {
            ClearAllControls();

        }

        private void SaveCommandAction()
        {
            this.IsBusy = true;
            this.BusyMessage = "Saving...";

            ctx.PreacherStudy(this.PreacherFullName, this.Title, this.Subtitle, this.Text, this.Tematica, this.Subiect,
                (result) =>
                {
                    this.IsBusy = false;

                    ClearAllControls();
                    GetPreachers();

                }, null);

        }

        private void DeleteCommandAction()
        {

        }

        #endregion

        #region Inline Study Editor

        private Visibility studyInlineVisibility;
        public Visibility StudyInlineVisibility
        {
            get
            {
                return this.studyInlineVisibility;
            }

            set
            {
                this.studyInlineVisibility = value;
                this.NotifyProperty("StudyInlineVisibility");
            }
        }

        #endregion
    }
}
